﻿////////////////////////////////////////////////////////////////////
//							_ooOoo_								  //
//						   o8888888o							  //
//						   88" . "88							  //
//						   (| ^_^ |)							  //
//						   O\  =  /O							  //
//						____/`---'\____							  //
//					  .'  \\|     |//  `.						  //
//					 /  \\|||  :  |||//  \						  //
//				    /  _||||| -:- |||||-  \						  //
//				    |   | \\\  -  /// |   |						  //
//					| \_|  ''\---/''  |   |						  //
//					\  .-\__  `-`  ___/-. /						  //
//				  ___`. .'  /--.--\  `. . ___					  //
//				."" '<  `.___\_<|>_/___.'  >'"".				  //
//			  | | :  `- \`.;`\ _ /`;.`/ - ` : | |				  //
//			  \  \ `-.   \_ __\ /__ _/   .-` /  /                 //
//		========`-.____`-.___\_____/___.-`____.-'========		  //
//				             `=---='                              //
//		^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^        //
//         佛祖保佑       永无BUG		永不修改				      //
////////////////////////////////////////////////////////////////////
using System;
using System.Collections.Generic;
using System.Windows.Forms;
using System.IO;
using System.Threading;
using ZhCun.Framework.Common;

namespace AccountManager
{
    static class Program
    {

        static Mutex mutex = new Mutex(true, "{35AEE812-632D-49C7-A2D6-71086FE573E3}");
        /// <summary>
        /// 应用程序的主入口点。
        /// </summary>
        [STAThread]
        static void Main()
        {
            if (!mutex.WaitOne(TimeSpan.Zero, true))
            {
                //"在同一时间只能运行一个软件".ShowAsInformation();
                //ApplicationAssistant.NotifyApplicationOnTop();
                MessageBox.Show("在同一时间只能运行一个软件!");
                return;
            }
            try
            {
                //处理未捕获的异常
                Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException);
                //处理UI线程异常  
                Application.ThreadException += new System.Threading.ThreadExceptionEventHandler(Application_ThreadException);
                //处理非UI线程异常  
                AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);

                Application.EnableVisualStyles();
                Application.SetCompatibleTextRenderingDefault(false);

                RunBeforeInitialize();
                if (new FrmLogin().ShowDialog() == DialogResult.OK)
                {
                    Application.Run(new FrmMDIMain());
                }
                else
                {
                    Application.Exit();
                }
            }
            catch (Exception ex)
            {
                string str = string.Empty;
                string strDateInfo = "出现应用程序未处理的异常：" + DateTime.Now.ToString() + "\r\n";
                if (ex != null) 
                    str = string.Format(strDateInfo + "异常类型：{0}\r\n异常消息：{1}\r\n异常信息：{2}\r\n",
     ex.GetType().Name, ex.Message, ex.StackTrace);
                else str = string.Format("①应用程序线程错误:{0}", ex);
                WriteUnhandledExceptionLogs(str);
                MessageBox.Show("发生致命错误，请及时联系开发人员！", "系统错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        /// <summary>
        /// 写未捕获的异常
        /// </summary>
        /// <param name="errMsg"></param>
        static void WriteUnhandledExceptionLogs(string errMsg)
        {
            //LogHelper.WriteLog("UnhandledException", errMsg);
            LogHelper.LogObj.Fatal(errMsg);
        }
        static void WriteUnhandledExceptionLogs(string errMsg,Exception ex)
        {
            //LogHelper.WriteLog("UnhandledException", errMsg);
            LogHelper.LogObj.Fatal(errMsg, ex);
        }

        /// <summary>
        /// 做法很多，可以是把出错详细信息记录到文本、数据库，发送出错邮件到作者信箱或出错后重新初始化等等         
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        static void Application_ThreadException(object sender, System.Threading.ThreadExceptionEventArgs e)
        {
            string str = "";
            string strDateInfo = "②出现应用程序未处理的异常：" + DateTime.Now.ToString() + "\r\n";
            Exception error = e.Exception as Exception;
            if (error != null)
                str = string.Format(strDateInfo + "异常类型：{0}\r\n异常消息：{1}\r\n异常信息：{2}\r\n", error.GetType().Name, error.Message, error.StackTrace);
            else
                str = string.Format("应用程序线程错误:{0}", e);
            WriteUnhandledExceptionLogs(str);
            MessageBox.Show("UI线程 发生致命错误，请及时联系开发人员！", "系统错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
        }

        static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
        {
            string str = "";
            Exception error = e.ExceptionObject as Exception;
            string strDateInfo = "③出现应用程序未处理的异常：" + DateTime.Now.ToString() + "\r\n";
            if (error != null) str = string.Format(strDateInfo + "Application UnhandledException:{0};\n\r堆栈信息:{1}", error.Message, error.StackTrace);
            else str = string.Format("Application UnhandledError:{0}", e);
            WriteUnhandledExceptionLogs(str);
            MessageBox.Show("非UI线程 发生致命错误，请停止当前操作并及时联系开发人员！", "系统错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
        }
        
        static readonly string RunAppUpdateName = "个人理财记账软件.exe.update";
        static readonly string RunAppName = "个人理财记账软件.exe";

        /// <summary>
        /// 程序运行前的初始化
        /// </summary>
        public static void RunBeforeInitialize()
        {
            //更新运行入口程序
            if (File.Exists(RunAppUpdateName))
            {
                //启动程序后可能主程序还没有退出,等待几秒中再替换入口程序
                ThreadPool.QueueUserWorkItem(new WaitCallback(a =>
                {
                    Thread.Sleep(5000);
                    File.Copy(RunAppUpdateName, RunAppName, true);
                    File.Delete(RunAppUpdateName);
                }));
            }
            if (!File.Exists("AccountManager.db"))
            {
                File.Copy("AccountManager.db.setup", "AccountManager.db");
            }
        }
    }
}